home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / ACORNUSERS / EMULATOR / MAGICKIT / assembler / c / expr < prev    next >
Text File  |  1998-04-14  |  7KB  |  425 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "defs.h"
  4. #include "externs.h"
  5.  
  6. int  push_val(int *ip);
  7. char check_keyword(void);
  8. int  push_op(char op);
  9. int  op_pri(char op);
  10. int  do_op(void);
  11.  
  12. char *keyword[4] = { "\4HIGH", "\3LOW", "\4PAGE", "\4BANK"};
  13. unsigned char op_stack[64] = { '' };
  14. unsigned long val_stack[64];
  15. struct t_symbol *vlablptr;
  16. int op_idx, val_idx;
  17. int vcount;
  18. int vflag;
  19.  
  20. /* evaluate expression */
  21.  
  22. evaluate(int *ip, char flag)
  23. {
  24.     int end, level;
  25.     unsigned char c;
  26.  
  27.     end = 0;
  28.     vflag = 0;
  29.     level = 0;
  30.     undef = 0;
  31.     op_idx = 0;
  32.     val_idx = 0;
  33.     value = 0;
  34.     val_stack[0] = 0;
  35.  
  36.     while (!end) {
  37.         c = prlnbuf[*ip];
  38.         if (isalnum(c) || c == '_' || c == '.') {
  39.             if (vflag == 1)
  40.                 goto error;
  41.             if (!push_val(ip))
  42.                 return (0);
  43.         }
  44.         else {
  45.             switch (c) {
  46.              case '$':
  47.             case '\'':
  48.                 if (vflag == 1)
  49.                     goto error;
  50.                 if (!push_val(ip))
  51.                     return (0);
  52.                 break;
  53.             case '(':
  54.                 if (vflag == 1)
  55.                     goto error;
  56.                 if (!push_op('('))
  57.                     return (0);
  58.                 level++;
  59.                 (*ip)++;
  60.                 break;
  61.             case ')':
  62.                 if (vflag == 0)
  63.                     goto error;
  64.                 if (level == 0)
  65.                     goto error;
  66.                 while (op_stack[op_idx] != '(') {
  67.                     if (!do_op())
  68.                         return (0);
  69.                 }
  70.                 op_idx--;
  71.                 level--;
  72.                 (*ip)++;
  73.                 break;
  74.             case '>':
  75.             case '<':
  76.                 if (vflag == 0)
  77.                     goto error;
  78.                 if (prlnbuf[++(*ip)] != c)
  79.                     goto error;
  80.                 if (!push_op(c))
  81.                     return (0);
  82.                 (*ip)++;
  83.                 break;
  84.             case '~':
  85.                 if (vflag == 1)
  86.                     goto error;
  87.                 if (!push_op(c))
  88.                     return (0);
  89.                 (*ip)++;
  90.                 break;
  91.             case '-':
  92.                 if (vflag == 0)
  93.                     c = '_';
  94.                 if (!push_op(c))
  95.                     return (0);
  96.                 (*ip)++;
  97.                 break;
  98.             case '%':
  99.             case '*':
  100.             case '&':
  101.                 if (vflag == 0) {
  102.                     if (!push_val(ip))
  103.                         return (0);
  104.                     break;
  105.                 }
  106.             case '+':
  107.             case '/':
  108.             case '^':
  109.             case '|':
  110.                 if (vflag == 0)
  111.                     goto error;
  112.                 if (!push_op(c))
  113.                     return (0);
  114.                 (*ip)++;
  115.                 break;
  116.             case ' ':
  117.             case '\t':
  118.                 (*ip)++;
  119.                 break;
  120.             case ';':
  121.             case '\0':
  122.                 end = 1;
  123.                 break;
  124.             case ',':
  125.                 end = 2;
  126.                 break;
  127.             default:
  128.                 end = 3;
  129.                 break;
  130.             }
  131.         }
  132.     }
  133.     if (vflag == 0)
  134.         goto error;
  135.     if (level != 0)
  136.         goto error;
  137.     while (op_stack[op_idx] != '') {
  138.         if (!do_op())
  139.             return (0);
  140.     }
  141.     value = val_stack[val_idx];
  142.     if (undef != 0) {
  143.         if (pass == LAST_PASS) {
  144.             error("Undefined symbol in operand field!");
  145. /*             return (0); */
  146.         }
  147.         value = 0;
  148.     }
  149.     switch (flag) {
  150.     case ';':
  151.         if (end != 1)
  152.             goto error;
  153.         (*ip)++;
  154.         break;
  155.     case ',':
  156.         if (end != 2)
  157.             goto error;
  158.         (*ip)++;
  159.         break;
  160.     }
  161.     return (1);
  162.  
  163. error:
  164.     error("Syntax error in expression!");
  165.     return(0);
  166. }
  167.  
  168. /* get a number and push it on the value stack */
  169.  
  170. push_val(int *ip)
  171. {
  172.     int     mul;
  173.     int     val;
  174.     char c;
  175.  
  176.     val = 0;
  177.     c = prlnbuf[*ip];
  178.     if (c == '*') {
  179.         val = (loccnt + (page << 13));
  180.         (*ip)++;
  181.     }
  182.     else if (c == '\'') {
  183.         (*ip)++;
  184.         val = prlnbuf[(*ip)++];
  185.         if ((prlnbuf[(*ip)++] != c) || (val == 0)) {
  186.             error("Syntax Error!");
  187.             return (0);
  188.         }
  189.     }
  190.     else if (isalpha(c) || c == '_' || c == '.') {
  191.         colsym(ip);
  192.         if (c = check_keyword()) {
  193.             if (!push_op(c))
  194.                 return (0);
  195.             else
  196.                 return (1);
  197.         }
  198.         if ((vlablptr = stlook()) == NULL)
  199.             undef = 1;
  200.         else if (vlablptr->type == UNDEF)
  201.             undef = 1;
  202.         else
  203.             val = vlablptr->value;
  204.         vcount++;
  205.     }
  206.     else {
  207.         if (c == '$')
  208.             mul = 16;
  209.         else if (c == '&')
  210.             mul = 8;
  211.         else if (c == '%')
  212.             mul = 2;
  213.         else if (c >= '0' && c <= '9') {
  214.             mul = 10;
  215.             val = c - '0';
  216.         }
  217.         for (;;) {
  218.             c = prlnbuf[++(*ip)];
  219.  
  220.             if (isdigit(c))
  221.                 c -= '0';
  222.             else if (isalpha(c)) {
  223.                 c = tolower(c);
  224.                 if (c >= 'a' && c <= 'f') {
  225.                     c -= 'a';
  226.                     c += 10;
  227.                 }
  228.                 else
  229.                     break;
  230.             }
  231.             else if (c == '_' && mul == 2)
  232.                 continue;
  233.             else
  234.                 break;
  235.             if (c >= mul)
  236.                 break;
  237.             val = (val * mul) + c;
  238.         }
  239.     }
  240.     if (val_idx == 63) {
  241.         error("Expression too complex!");
  242.         return (0);
  243.     }
  244.     val_idx++;
  245.     val_stack[val_idx] = val;
  246.     vflag = 1;
  247.     return(1);
  248. }
  249.  
  250. /* verify a keyword */
  251.  
  252. char check_keyword(void)
  253. {
  254.     char c = 0;
  255.  
  256.     if (!strnicmp(symbol, keyword[0], 5))
  257.         c = 'h';
  258.     else if (!strnicmp(symbol, keyword[1], 4))
  259.         c = 'l';
  260.     else if (!strnicmp(symbol, keyword[2], 5))
  261.         c = 'p';
  262.     else if (!strnicmp(symbol, keyword[3], 5))
  263.         c = 'b';
  264.  
  265.     if (c == 'p' || c == 'b') {
  266.         vlablptr = NULL;
  267.         vcount = 0;
  268.     }
  269.     return (c);
  270. }
  271.  
  272. /* push an operator on the stack */
  273.  
  274. push_op(char op)
  275. {
  276.     if (op != '(') {
  277.         while (op_pri(op_stack[op_idx]) >= op_pri(op)) {
  278.             if (!do_op())
  279.                 return (0);
  280.         }
  281.     }
  282.     if (op_idx == 63) {
  283.         error("Expression too complex!");
  284.         return (0);
  285.     }
  286.     op_idx++;
  287.     op_stack[op_idx] = op;
  288.     vflag = 0;
  289.     return (1);
  290. }
  291.  
  292. /* return the priority of an operator */
  293.  
  294. op_pri(char op)
  295. {
  296.     int pri = 0;
  297.  
  298.     switch (op) {
  299.     case 'b':
  300.     case 'h':
  301.     case 'l':
  302.     case 'p':
  303.     case '_':
  304.     case '~':
  305.         pri++;
  306.         pri++;
  307.     case '*':
  308.     case '/':
  309.     case '%':
  310.         pri++;
  311.     case '+':
  312.     case '-':
  313.         pri++;
  314.     case '<':
  315.     case '>':
  316.         pri++;
  317.         pri++;
  318.         pri++;
  319.     case '&':
  320.         pri++;
  321.     case '^':
  322.         pri++;
  323.     case '|':
  324.         pri++;
  325.     case '':
  326.     case '(':
  327.         break;
  328.     }
  329.     return (pri);
  330. }
  331.  
  332. /* apply an operator to the value stack */
  333.  
  334. do_op(void)
  335. {
  336.     unsigned long val[2];
  337.     char op;
  338.  
  339.     op = op_stack[op_idx--];
  340.     val[0] = val_stack[val_idx];
  341.     if (op_pri(op) < 10)
  342.         val[1] = val_stack[--val_idx];
  343.     switch (op) {
  344.     case 'p':
  345.         if (vcount != 1) {
  346.             if (vcount == 0)
  347.                 error("No symbol in function PAGE!");
  348.             else
  349.                 error("Too many symbols in function PAGE!");
  350.             return (0);
  351.         }
  352.         if (vlablptr)
  353.             val[0] = vlablptr->page;
  354.         break;
  355.     case 'b':
  356.         if (vcount != 1) {
  357.             if (vcount == 0)
  358.                 error("No symbol in function BANK!");
  359.             else
  360.                 error("Too many symbols in function BANK!");
  361.             return (0);
  362.         }
  363.         if (vlablptr)
  364.             val[0] = vlablptr->bank;
  365.         break;
  366.     case 'h':
  367.         val[0] = (val[0] & 0xFF00) >> 8;
  368.         break;
  369.     case 'l':
  370.         val[0] = val[0] & 0xFF;
  371.         break;
  372.     case '+':
  373.         val[0] = val[1] + val[0];
  374.         break;
  375.     case '-':
  376.         val[0] = val[1] - val[0];
  377.         break;
  378.     case '*':
  379.         val[0] = val[1] * val[0];
  380.         break;
  381.     case '/':
  382.         if (val[0] == 0) {
  383.             error("Divide by zero!");
  384.             return (0);
  385.         }
  386.         val[0] = val[1] / val[0];
  387.         break;
  388.     case '%':
  389.         if (val[0] == 0) {
  390.             error("Divide by zero!");
  391.             return (0);
  392.         }
  393.         val[0] = val[1] % val[0];
  394.         break;
  395.     case '_':
  396.         val[0] = -val[0];
  397.         break;
  398.     case '<':
  399.         val[0] = val[1] << (val[0] & 0x1F);
  400.         break;
  401.     case '>':
  402.         val[0] = val[1] >> (val[0] & 0x1f);
  403.         break;
  404.     case '|':
  405.         val[0] = val[1] | val[0];
  406.         break;
  407.     case '^':
  408.         val[0] = val[1] ^ val[0];
  409.         break;
  410.     case '&':
  411.         val[0] = val[1] & val[0];
  412.         break;
  413.     case '~':
  414.         val[0] = ~val[0];
  415.         break;
  416.     default:
  417.         error("Invalid operator in expression!");
  418.         return (0);
  419.     }
  420.  
  421.     val_stack[val_idx] = val[0];
  422.     return (1);
  423. }
  424.  
  425.